package navigation;

import config.*;

/**
 * Navigator that goes to an exit and prefers to go right
 *
 * Prioritys: unknown right, unknown forward, unknown left, unknown backward,
 * known right, known forward, known left, known backward.
 * Does not drive into known deadends.
 * Prefers exits.
 *
 * @author hyurah
 */

public class GoRightExitNavigator extends Navigator{

	/**
	 * Constructs an GoRightExitNavigator with data specified by the old navigator
	 *
	 * @param oldNavigator old navigator for data retrievel
	 */

	public GoRightExitNavigator(Navigator oldNavigator) {
		super(oldNavigator);
	}

	/**
	 * Decide direction to drive to next
	 *
	 * @return direction to drive to or -1 if destination is reached
	 */

	public int decideDirection() {
		int rotation = Config.GORIGHT? Direction.LEFT : Direction.RIGHT;
		int direction = Config.GORIGHT? Direction.RIGHT : Direction.LEFT;
		int xTarget;
		int yTarget;
		if(map.fieldIsExit(xPosition, yPosition)) {
			direction=-1;
		} else {
			boolean found=false;
			for(int i=0; i<4 && !found; i++) {
				if(isPassable((direction+facingDirection)%4)) {
					xTarget = xPosition;
					yTarget = yPosition;
					switch((direction+facingDirection)%4) {
						case Direction.NORTH: yTarget--; break;
						case Direction.EAST: xTarget++; break;
						case Direction.SOUTH: yTarget++; break;
						case Direction.WEST: xTarget--; break;
					}
					if(map.fieldIsExit(xTarget, yTarget)) {
						found=true;
					}
				}
				if(!found) {
					direction=(direction+rotation)%4;
				}
			}
			for(int i=0; i<4 && !found; i++) {
				if(isPassable((direction+facingDirection)%4)) {
					xTarget = xPosition;
					yTarget = yPosition;
					switch((direction+facingDirection)%4) {
						case Direction.NORTH: yTarget--; break;
						case Direction.EAST: xTarget++; break;
						case Direction.SOUTH: yTarget++; break;
						case Direction.WEST: xTarget--; break;
					}
					if(!map.fieldIsKnown(xTarget, yTarget)) {
						found=true;
					}
				}
				if(!found) {
					direction=(direction+rotation)%4;
				}
			}
			for(int i=0; i<3 && !found; i++) {
				if(isPassable((direction+facingDirection)%4)) {
					xTarget = xPosition;
					yTarget = yPosition;
					switch((direction+facingDirection)%4) {
						case Direction.NORTH: yTarget--; break;
						case Direction.EAST: xTarget++; break;
						case Direction.SOUTH: yTarget++; break;
						case Direction.WEST: xTarget--; break;
					}
					if(!map.fieldIsDeadEnd(xTarget, yTarget)) {
						found=true;
					}
				}
				if(!found) {
					direction=(direction+rotation)%4;
				}
			}
		}
		return direction;
	}

}
